#!/usr/bin/python
# -*-coding:utf-8-*-
import os
import pandas as pd
import numpy as np

### 底层读取数据的依赖（不提供）
from zbc_factor_lib.base.factors_library_base import NewRQFactorLib as DataReader

from dir_info import raw_X_data_dir
from dir_info import cache_data_dir

financial_data_start_date='2008-01-01'
financial_data_end_date='2019-09-30'

####
common_cols = ['stock_code', 'report_date', 'declare_date']

income_sheet_used_items = [
    'basic_eps',
    'diluted_eps',
    'financial_expenses',
    'general_and_administrative_expenses',
    'investment_income',
    'minority_interest_income',
    'minus_income_tax_expenses',
    'net_profit',
    'net_profit_attributable_to_shareholders_of_parent_company',
    'non_operating_expenses',
    'non_operating_profit',
    'operating_income',
    'operations_expenses',
    'operations_taxes_and_surcharges',
    'overall_costs',
    'overall_income',
    'profit_before_tax',
    'profit_from_operations',
    'selling_and_distribution_expenses',
    'impairment_loss_on_assets',
]

cashflow_sheet_used_items = [
    'cash_and_cash_equivalents_at_beginning',
    'cash_and_cash_equivalents_at_end',
    'cash_payments_for_construction_intangible_long_term_assets',
    'cash_payments_for_dividends_profits_interest',
    'cash_payments_for_goods_and_services',
    'cash_received_from_borrowings',
    'cash_received_from_sales',
    'cash_repayments_of_amounts_borrowed',
    'employees_cash_payments',
    'net_cash_flows_from_financing_act',
    'net_cash_flows_from_opt_act',
    'net_cashflows_from_investing_act',
    'net_increase_in_cash_and_cash_equivalent',
    'other_cash_payments_relating_to_op_act',
    'other_cash_received_from_op_act',
    'payments_of_taxes',
    'sub_total_of_cashin_flows_from_financing_act',
    'sub_total_of_cashin_flows_from_op_act',
    'sub_total_of_cashout_flows_from_financing_act',
    'sub_total_of_cashout_flows_from_investing_act',
    'subtotal_cashin_flows_from_investing_act',
    'subtotal_of_cash_outflows_from_opt_act',
]

balance_sheet_used_items = [
    'accounts_payable',
    'accounts_receivable',
    'accrued_expenses',
    'accrued_wages',
    'advances_from_customers',
    'capital_reserve',
    'cash',
    'deferred_tax_assets',
    'equity',
    'intangible_assets',
    'inventory',
    'long_term_equity_investment',
    'long_term_prepaid_expenses',
    'minority_equity',
    'notes_payable_and_accounts_payable',
    'notes_receivable',
    'notes_receivable_and_accounts_receivable',
    'short_term_borrowing',
    'surplus_reserve',
    'taxes_and_dues',
    'total_assets',
    'total_construction_in_progress',
    'total_current_assets',
    'total_current_liabilities',
    'total_equity',
    'total_equity_attributable_to_shareholders',
    'total_fixed_asset',
    'total_liabilities',
    'total_liabilities_and_owners_equity',
    'total_non_current_assets',
    'total_non_current_liabilities',
    'total_other_payable',
    'total_receivable_other',
    'total_share_capital',
    'undistributed_profits',
    'construction_in_progress',
    'fixed_asset',
    'other_payable',
    'receivable_other',
]

###
data_reader = DataReader()
# data_reader.show_basic_library_db()

def get_raw_financial_statement_data_v1():
    ###### TODO - read data
    processed_income_sheet_data = data_reader.read_basic_data_table('processed_income_sheet_data')
    processed_balance_sheet_data = data_reader.read_basic_data_table('processed_balance_sheet_data')
    processed_cashflow_sheet_data = data_reader.read_basic_data_table('processed_cashflow_sheet_data')
    processed_single_season_cashflow_sheet_data = data_reader.read_basic_data_table('processed_single_season_cashflow_sheet_data')
    processed_single_season_income_sheet_data = data_reader.read_basic_data_table('processed_single_season_income_sheet_data')

    # rename
    processed_income_sheet_data = processed_income_sheet_data.rename(columns={'code': 'stock_code'})
    processed_balance_sheet_data = processed_balance_sheet_data.rename(columns={'code': 'stock_code'})
    processed_cashflow_sheet_data = processed_cashflow_sheet_data.rename(columns={'code': 'stock_code'})
    processed_single_season_cashflow_sheet_data = processed_single_season_cashflow_sheet_data.rename(columns={'code': 'stock_code'})
    processed_single_season_income_sheet_data = processed_single_season_income_sheet_data.rename(columns={'code': 'stock_code'})

    # TODO - fiter date
    processed_income_sheet_data = processed_income_sheet_data[processed_income_sheet_data['report_date']>=financial_data_start_date]
    processed_balance_sheet_data = processed_balance_sheet_data[processed_balance_sheet_data['report_date']>=financial_data_start_date]
    processed_cashflow_sheet_data = processed_cashflow_sheet_data[processed_cashflow_sheet_data['report_date']>=financial_data_start_date]

    processed_income_sheet_data = processed_income_sheet_data[processed_income_sheet_data['report_date']<=financial_data_end_date]
    processed_balance_sheet_data = processed_balance_sheet_data[processed_balance_sheet_data['report_date']<=financial_data_end_date]
    processed_cashflow_sheet_data = processed_cashflow_sheet_data[processed_cashflow_sheet_data['report_date']<=financial_data_end_date]

    processed_single_season_cashflow_sheet_data = \
        processed_single_season_cashflow_sheet_data[processed_single_season_cashflow_sheet_data['report_date']>=financial_data_start_date]
    processed_single_season_income_sheet_data = \
        processed_single_season_income_sheet_data[processed_single_season_income_sheet_data['report_date']>=financial_data_start_date]

    # TODO - 选择项
    # income sheet
    processed_income_sheet_data = processed_income_sheet_data[common_cols+income_sheet_used_items]

    # 单季度
    processed_single_season_income_sheet_data = processed_single_season_income_sheet_data[common_cols+income_sheet_used_items]

    income_sheet_used_items_for_single = [c+'_seasonal' for c in income_sheet_used_items]
    processed_single_season_income_sheet_data.columns = common_cols+income_sheet_used_items_for_single

    # cashflow sheet
    processed_cashflow_sheet_data = processed_cashflow_sheet_data[common_cols+cashflow_sheet_used_items]

    # 单季度
    processed_single_season_cashflow_sheet_data = processed_single_season_cashflow_sheet_data[common_cols+cashflow_sheet_used_items]

    cashflow_sheet_used_items_for_single = [c+'_seasonal' for c in cashflow_sheet_used_items]
    processed_single_season_cashflow_sheet_data.columns = common_cols+cashflow_sheet_used_items_for_single

    # balance sheet
    processed_balance_sheet_data = processed_balance_sheet_data[common_cols+balance_sheet_used_items]

    # TODO - 得到相同的declare date
    processed_income_sheet_data = processed_income_sheet_data.set_index(['report_date', 'stock_code'])
    processed_single_season_income_sheet_data = processed_single_season_income_sheet_data.set_index(['report_date', 'stock_code'])
    processed_cashflow_sheet_data = processed_cashflow_sheet_data.set_index(['report_date', 'stock_code'])
    processed_single_season_cashflow_sheet_data = processed_single_season_cashflow_sheet_data.set_index(['report_date', 'stock_code'])
    processed_balance_sheet_data = processed_balance_sheet_data.set_index(['report_date', 'stock_code'])

    ##
    code_report_date_declare_date = processed_balance_sheet_data[['declare_date']].copy()

    code_report_date_declare_date = code_report_date_declare_date.rename(columns={'declare_date': 'balance_declare_date'})

    code_report_date_declare_date['income_declare_date'] = processed_income_sheet_data.loc[code_report_date_declare_date.index, 'declare_date']

    code_report_date_declare_date['cashflow_declare_date'] = \
        processed_cashflow_sheet_data.loc[code_report_date_declare_date.index, 'declare_date']

    code_report_date_declare_date['declare_date'] = code_report_date_declare_date[['income_declare_date',
                                                                                     'balance_declare_date',
                                                                                     'cashflow_declare_date']].max(axis=1)

    processed_income_sheet_data = processed_income_sheet_data.drop('declare_date', axis=1)
    processed_single_season_income_sheet_data = processed_single_season_income_sheet_data.drop('declare_date', axis=1)
    processed_cashflow_sheet_data = processed_cashflow_sheet_data.drop('declare_date', axis=1)
    processed_single_season_cashflow_sheet_data = processed_single_season_cashflow_sheet_data.drop('declare_date', axis=1)
    processed_balance_sheet_data = processed_balance_sheet_data.drop('declare_date', axis=1)

    # TODO - 合并
    merge_financial_statement_data = pd.concat([processed_balance_sheet_data,
                                                processed_income_sheet_data,
                                                processed_cashflow_sheet_data,
                                                processed_single_season_income_sheet_data,
                                                processed_single_season_cashflow_sheet_data], axis=1)

    # TODO - KEY排序
    merge_financial_statement_data = \
        merge_financial_statement_data.sort_index(level=['stock_code', 'report_date'], ascending=True)

    merge_financial_statement_data = merge_financial_statement_data.astype(np.float32)

    # TODO －构建目标
    target_construction_label = code_report_date_declare_date.loc[merge_financial_statement_data.index, ['declare_date']]

    # TODO - 保存
    merge_financial_statement_data.to_hdf(os.path.join(raw_X_data_dir, 'X_financial_statement_data_v1.h5'),
                                          key='X_financial_statement_data_v1',
                                          mode='w',
                                          format='table')

    target_construction_label.to_hdf(os.path.join(cache_data_dir, 'X_financial_statement_data_target_construction_label.h5'),
                                  key='X_financial_statement_data_target_construction_label',
                                  mode='w',
                                  format='table')

    print('get raw financial statement data v1 done!\n')


if __name__ == '__main__':
    get_raw_financial_statement_data_v1()

